
function pack_patch(q) {
	var p = q['patch'][0];
	if ('cartwheel-tiling' == p) { return pack_cartwheel(q); }
	if ('repeating-decimal' == p) { return pack_repeating(q); }
	if ('hypotrochoid' == p) { return pack_trochoid(q); }
	if ('epitrochoid' == p) { return pack_trochoid(q); }
	return [];
}

function unpack_patch(s) {
	var q = [];
	var a = s.split('_');
	var p = a[0];
	if ('c' == p) { return unpack_cartwheel(a); }
	if ('r' == p) { return unpack_repeating(a); }
	if ('h' == p) { return unpack_trochoid(a); }
	if ('e' == p) { return unpack_trochoid(a); }
}

function pack_integer(s) {
	var n = parseInt(s + '');
	if (isNaN(n)) { return '0'; }
	return n.toString(36);
}

function unpack_integer(s) {
	var n = parseInt(s + '', 36);
	if (isNaN(n)) { return null; }
	return n;
}

function unpack_trochoid(a) {
	var q = [];
	if ('e' == a[0]) { q['patch'] = ['epitrochoid']; }
	else if ('h' == a[0]) { q['patch'] = ['hypotrochoid']; }
	else {return q;}

	q['big_r'] = [unpack_integer(a[1])];
	q['little_r'] = [unpack_integer(a[2])];
	q['d'] = [unpack_integer(a[3])];
	return q;
}

function pack_trochoid(q) {
	var a = [];
	if ('hypotrochoid' == q['patch'][0]) { a.push('h'); }
	else if ('epitrochoid' == q['patch'][0]) { a.push('e'); }
	else { return ''; }
	a.push(pack_integer(q['big_r'][0]));
	a.push(pack_integer(q['little_r'][0]));
	a.push(pack_integer(q['d'][0]));
	return a.join('_');
}

function unpack_repeating(a) {
	var q = [];
	q['patch'] = ['repeating-decimal'];
	q['numerator'] = [unpack_integer(a[1])];
	q['denominator'] = [unpack_integer(a[2])];
	q['base'] = [unpack_integer(a[3])];
	return q;
}

function pack_repeating(q) {
	var a = ['r'];
	a.push(pack_integer(q['numerator'][0]));
	a.push(pack_integer(q['denominator'][0]));
	a.push(pack_integer(q['base'][0]));
	return a.join('_');
}

function unpack_cartwheel(a) {
	var q = [];
	q['patch'] = ['cartwheel-tiling'];
	var o = a[1].split('');
	var k = {
		'1': 'p1',
		'2': 'p2',
		'3': 'p3',
		'a': 'arcs',
		'b': 'bars',
		'c': 'rings',
		'd': 'cartwheel',
		'e': 'edges',
		'f': 'colors',
		'g': 'decagon',
		'h': 'gray'
	};

	for (var i in o) {
		if (null != k[o[i]]) {
			q[k[o[i]]] = [1];
		}
	}

	q['s0'] = [unpack_integer(a[2])];
	q['s1'] = [unpack_integer(a[3])];
	q['s2'] = [unpack_integer(a[4])];
	q['s3'] = [unpack_integer(a[5])];
	q['s4'] = [unpack_integer(a[6])];

	q['x'] = [unpack_float(a[7])];
	q['y'] = [unpack_float(a[8])];
	q['z'] = [unpack_float(a[9])];

	return q;
}

function unpack_float(s) {
	return unpack_integer(s) / 10000;
}

function pack_float(s) {
	return pack_integer(Math.round(parseFloat('' + s) * 10000));
}

function pack_cartwheel(q) {
	var a = ['c'];
	var o = '';
	if (1 == q['p1']) { o += '1'; }
	if (1 == q['p2']) { o += '2'; }
	if (1 == q['p3']) { o += '3'; }
	if (1 == q['arcs']) { o += 'a'; }
	if (1 == q['bars']) { o += 'b'; }
	if (1 == q['rings']) { o += 'c'; }
	if (1 == q['cartwheel']) { o += 'd'; }
	if (1 == q['edges']) { o += 'e'; }
	if (1 == q['colors']) { o += 'f'; }
	if (1 == q['decagon']) { o += 'g'; }
	if (1 == q['gray']) { o += 'h'; }

	a.push(o);
	a.push(pack_integer(q['s0']));
	a.push(pack_integer(q['s1']));
	a.push(pack_integer(q['s2']));
	a.push(pack_integer(q['s3']));
	a.push(pack_integer(q['s4']));
	a.push(pack_float(q['x']));
	a.push(pack_float(q['y']));
	a.push(pack_float(q['z']));

	return a.join('_');
}
